package 多线程;


import java.lang.reflect.Array;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.concurrent.*;

/**
 * @author : K k
 * @date : 10:25 2020/8/21
 * this 指的 一个对象实例对应一个this 也就是说synchronized锁住的是不同对象实例的monitor
 * 1.synchronized加到静态方法上 调用静态方法时会锁住此类，如果此类有2个静态方法都加上了synchronized则同一时刻只能有一个静态方法被调用
 * 2.synchronized加到普通方法上 该类的实例（实例指new出来的对象）同一时刻只能调用一个方法，如果多个线程同时调用该实例的多个synchronized方法则只有一个线程会调用到，其他线程会阻塞等待获取锁
 * 3.synchronized(obj)放到方法里面作为代码块锁时则要看锁住的对象是什么:
 */
public class SynchronizedDemo1 {
    public  void method1(){
        try {
            synchronized (this) {
                System.out.println("Method 1 start");
                this.wait();
                Thread.sleep(3000);
                System.out.println("Method 1 execute");
                System.out.println("Method 1 end");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public void method2(){
        System.out.println("Method 2 start");

        try {
            synchronized (this) {
                System.out.println("Method 2 execute");
                Thread.sleep(3000);
                this.notifyAll();
                System.out.println("Method 2 end");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(2);
        final SynchronizedDemo1 test1 = new SynchronizedDemo1();
        final SynchronizedDemo1 test2 = new SynchronizedDemo1();

        Future<Integer> submit1 = executorService.submit(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                test1.method1();
                return 1;
            }
        });
        Future<Integer> submit2 = executorService.submit(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                test1.method2();
                return 2;
            }
        });
        System.out.println(submit1 + "-" + submit2);

        Thread thread1=new Thread(new Runnable() {
            @Override
            public void run() {
                test1.method1();
            }
        });

        Thread thread2=new Thread(new Runnable() {
            @Override
            public void run() {
                test1.method2();
            }
        });

        try {
            //thread1.setDaemon(true);
            thread1.start();
            thread2.start();
            thread1.join();
            thread2.join();
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("搞定");
        /*SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String format = simpleDateFormat.format(new Date());
        System.out.println(format);*/

    }
}